package com.shiro.realm;

import com.bean.User;
import com.service.IUserService;
import com.shiro.token.CustomLoginToken;
import com.shiro.token.JWTToken;
import com.utils.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Set;

/**
 * @author WxrStart
 * @create 2022-05-20 8:56
 */
@Slf4j
public class CustomerRealm extends AuthorizingRealm {
    @Autowired
    private IUserService iuserService;


    /**
     * 限定这个 Realm 只处理 UsernamePasswordToken
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        log.info("CustomerRealm的supports调用了");
        return token instanceof CustomLoginToken;
    }


    /**
     ** 获取角色与权限
     *doGetAuthorizationInfo执行时机有三个，如下：
     *  1、subject.hasRole(“admin”) 或 subject.isPermitted(“admin”)：自己去调用这个是否有什么角色或者是否有什么权限的时候；
     *  2、@RequiresRoles("admin") ：在方法上加注解的时候；
     *  3、@shiro.hasPermission name = "admin"/@shiro.hasPermission："dustin:test"在页面上加shiro标签的时候，即进这个页面的时候扫描到有这个标签的时候。
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//        log.info("CustomerRealm的doGetAuthentizationInfo调用了");
//        // 获取当前用户
//        User user  = (User) SecurityUtils.getSubject().getPrincipal();
//        // 查询数据库，获取用户的角色信息
//        String userRole = user.getUserRole();
//        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//        info.addRole(userRole);
//        return info;
        return null;

    }

    /**
     * 登录信息验证
     * 1.doGetAuthenticationInfo执行时机如下
     * 当调用Subject currentUser = SecurityUtils.getSubject();
     * currentUser.login(token);
     * 2.验证token，取代原来的账号密码认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
            log.info("CustomerRealm的doGetAuthenticationInfo调用了");
            // 从 AuthenticationToken 中获取当前用户email
            String email = (String) token.getPrincipal();
            // 解密获得username，用于和数据库进行对比
            User user = iuserService.findByEmail(email);
            if (email == null) {
                throw new AuthenticationException("token无效");
            }
            return new SimpleAuthenticationInfo(user.getEmail(),user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName());

        }



    @Override
    public String getName() {
        log.info("CustomerRealm的getName调用了");
        return "UserRealm";
    }
}